package com.jeffmony.sample;

import android.app.Activity;
import android.graphics.SurfaceTexture;
import android.net.Network;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.webkit.WebView;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.VideoView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.google.gson.Gson;
import com.jeffmony.playersdk.IPlayer;
import com.jeffmony.playersdk.JeffPlayer;
import com.jeffmony.playersdk.common.PlayerSettings;
import com.jeffmony.playersdk.common.PlayerType;
import com.jeffmony.playersdk.common.SeekType;
import com.jeffmony.videocache.VideoProxyCacheManager;
import com.jeffmony.videocache.listener.IVideoCacheListener;
import com.jeffmony.videocache.model.VideoCacheInfo;
import com.jeffmony.videocache.utils.LogUtils;
import com.jeffmony.videocache.utils.ProxyCacheUtils;
import com.jeffmony.videocache.utils.TimeUtils;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MulticastSocket;
import java.net.Proxy;
import java.net.Socket;
import java.net.SocketException;
import java.net.URL;
import java.util.Properties;

public class VideoPlayActivity extends Activity {

    private static final String TAG = "VideoPlayActivity";

    private final static int MSG_UPDATE_VIDEOSIZE = 1;
    private final static int MSG_UPDATE_VIDEOTIME = 2;

    private final static int MAX_PROGRESS = 1000;

    private String mVideoUrl;
    private int mPlayerType;
    private Surface mSurface;
    private JeffPlayer mPlayer;
    private Size mScreenSize;
    private int mVideoWidth;
    private int mVideoHeight;
    private boolean mLocalProxyEnable;
    private boolean mUseOkHttpEnable;

    private TextureView mVideoView;

    private VideoView videoView;

    private WebView webView;


    private SeekBar mProgressView;
    private TextView mTimeView;
    private ImageButton mVideoStatusBtn;
    private VideoStatus mVideoStatus;

    private  String playUrl;


    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            if (msg.what == MSG_UPDATE_VIDEOSIZE) {
                updateVideoSurfaceSize(mVideoWidth, mVideoHeight);
            } else if (msg.what == MSG_UPDATE_VIDEOTIME) {
                updateVideoTimeInfo();
            }
        }
    };
    public static final int DEFAULT_MAX_PACKET_SIZE = 2000;
    private byte[] packetBuffer;
    private int packetRemaining;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video_play);
        mScreenSize = ScreenUtils.getScreenSize(this.getApplicationContext());

        mVideoUrl = getIntent().getStringExtra("video_url");
        mLocalProxyEnable = getIntent().getBooleanExtra("local_proxy_enable", false);
        mUseOkHttpEnable = getIntent().getBooleanExtra("use_okttp_enable", false);
        mPlayerType = getIntent().getIntExtra("player_type", 1);

        ProxyCacheUtils.getConfig().setUseOkHttp(mUseOkHttpEnable);

        mVideoView = findViewById(R.id.video_textureview);
        mProgressView = findViewById(R.id.video_progress_view);
        mTimeView = findViewById(R.id.video_time_view);
        mVideoStatusBtn = findViewById(R.id.video_status_btn);
        webView = findViewById(R.id.webView);
        videoView = findViewById(R.id.videoView);

        mVideoView.setSurfaceTextureListener(mTextureListener);
        mProgressView.setOnSeekBarChangeListener(mOnSeekBarChangeListener);
        mVideoStatusBtn.setOnClickListener(mOnClickListener);


        if(mPlayerType == 0) { //webVie加载
            mVideoView.setVisibility(View.GONE);
            webView.setVisibility(View.VISIBLE);
//


            String serverIP = "127.0.0.1";  // 服务器的 IP 地址

            new Thread(new Runnable() {
                @Override
                public void run() {
                    // 在这里执行网络请求代码



//                    int port = Integer.parseInt(playUrl.substring(17,22));  // 服务器的端口
//                    try (Socket socket = new Socket(InetAddress.getByName(serverIP), port)) {
                        // 向服务器发送数据
//                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//                writer.write("Hello from Android!");
//                writer.newLine();
//                writer.flush();

//                    try {
//                        Socket socket = new Socket("127.0.0.1", Integer.parseInt(playUrl.substring(17,22)));
//                        Log.d(TAG,"initPlayerSettings socket connect" + socket.isConnected());
//                        socket.setSoTimeout(600000);
//                        InputStream is = socket.getInputStream();
//// 步骤2：创建输入流读取器对象 并传入输入流对象
//// 该对象作用：获取服务器返回的数据
//                        Log.e(TAG,"initPlayerSettings 客户端接收的信息1");
//                        InputStreamReader isr = new InputStreamReader(is);
//                        Log.e(TAG,"initPlayerSettings 客户端接收的信息2");
//                        BufferedReader br = new BufferedReader(isr);
//                        Log.e(TAG,"initPlayerSettings 客户端接收的信息3");
//// 步骤3：通过输入流读取器对象 接收服务器发送过来的数据
//                        String info = null;
//                        int linecount=1;
//                        Log.e(TAG,"initPlayerSettings 客户端接收的信息4");
//                        StringBuilder sb = new StringBuilder();
//                        while((info = br.readLine())!=null){
//                           Log.e(TAG,"initPlayerSettings 客户端接收的信息，第 "+(linecount++)+" 行："+info);
//                            sb.append(info);
//                        }
//                        Log.e(TAG,"initPlayerSettings 客户端接收的信息4" + sb.toString());
//                        Log.e(TAG,"initPlayerSettings 客户端接收的信息5 = " + sb.length());


//                        Log.d(TAG,"initPlayerSettings socket connect" + socket.isConnected());
//                        byte[] test = "这是服务端要接收的消息".getBytes();


//                    } catch (IOException e) {
//                        throw new RuntimeException(e);
//                    }
//                    DatagramSocket  socket = null;
//                    DatagramPacket packet = null;
//                    InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1", Integer.parseInt(playUrl.substring(17,22)));
//                    try {
//                        packetBuffer = new byte[DEFAULT_MAX_PACKET_SIZE];
//                        packet = new DatagramPacket(packetBuffer, 0, DEFAULT_MAX_PACKET_SIZE);
//                        socket = new DatagramSocket(socketAddress);
//                        socket.setSoTimeout(1000 * 90);
//                        socket.receive(packet);
//                        int packetOffset = packet.getLength() - packetRemaining;
//                        Log.d(TAG,"initPlayerSettings response playUrl alle packetOffset " + packetOffset );
//                    } catch (IOException e) {
//                        Log.d(TAG,"initPlayerSettings response playUrl alle " + e.toString() );
//                        throw new RuntimeException(e);
//                    }
//                    mVideoUrl = "https://rmt.higozj.com/profile/upload/2024/05/15/20240515160348A016.mp4";
                    playUrl = ProxyCacheUtils.getProxyUrl(Uri.parse(mVideoUrl).toString(), null, null);
//                    readWebsite(playUrl);
                    VideoProxyCacheManager.getInstance().startRequestVideoInfo(mVideoUrl, null, null);
                    String value = "GET " + playUrl.substring(22,playUrl.length())+ " HTTP/1.1";
                    SocketResponseDTO response = SocketClient.request("127.0.0.1", Integer.parseInt(playUrl.substring(17,22)), value);
                    Log.d(TAG,"initPlayerSettings response playUrl all " + playUrl);//
                    Log.d(TAG,"initPlayerSettings response playUrl  " + value);//
                    Log.d(TAG,"initPlayerSettings response" + new Gson().toJson(response));//
//                    webView.loadUrl(playUrl);
//                    Log.d(TAG, "initPlayerSettings loadUrl" + playUrl.substring(0,22));
//                    if (TextUtils.isEmpty(response.getErrorMsg())) {
//                        System.out.println("错误消息：" + response.getErrorMsg());
//                        Log.d(TAG,"initPlayerSettings socket 错误消息" + response.getErrorMsg());
//                    } else {
//                            Log.d(TAG,"initPlayerSettings socket 客户端收到消息" + new String(response.getResponse()));
////                        System.out.println("客户端收到消息：" + new String(response.getResponse()));
//                    }


                    // 输出数据流
//                    OutputStream socketOutputStream = socket.getOutputStream();
//                     输入数据流
//                    InputStream socketInputStream = socket.getInputStream();



                        // 从服务器接收数据
//                        InputStreamReader inputStreamReader = new InputStreamReader(socket.getInputStream());
//                        BufferedReader reader = new BufferedReader(inputStreamReader);
//                        String response = reader.readLine();
//                        Log.d(TAG,"response" +response.length());
//                        String line;
//                        while ((line = reader.readLine())!= null) {
////                            System.out.println(line);
//                            Log.d(TAG,"response" +line);
//                        }
                        Log.d(TAG,"initPlayerSettings" + isProxyReachable("127.0.0.1"));
//                        Log.d(TAG,"response" + inputStreamReader.getEncoding());

//                        Log.d(TAG, "initPlayerSettings loadUrl" + isProxyValid("127.0.0.1", Integer.parseInt(playUrl.substring(17,22))));
//                    } catch (IOException e) {
//                        Log.d(TAG,"response" + e.toString());
//                        e.printStackTrace();
//                    }
                }
            }).start();



//            webView.getSettings().setAllowUniversalAccessFromFileURLs(true);
//            webView.getSettings().setAllowFileAccessFromFileURLs(true);
//            webView.loadUrl(playUrl);

//            Log.d(TAG, "initPlayerSettings loadUrl" + isProxyValid("127.0.0.1", Integer.parseInt(playUrl.substring(17,22))));

        }else if(mPlayerType == 3){
            String playUrl = ProxyCacheUtils.getProxyUrl(Uri.parse(mVideoUrl).toString(), null, null);
            mVideoView.setVisibility(View.GONE);
            videoView.setVisibility(View.VISIBLE);
            videoView.setVideoURI(Uri.parse(playUrl));
            videoView.start();
        }
    }


    public void readWebsite(String urlString) {
        try {
            URL url = new URL(urlString);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            int responseCode = connection.getResponseCode();
            Log.d(TAG,"WebResponse responseCode"+ responseCode);
            if (responseCode == HttpURLConnection.HTTP_OK) {
                InputStream inputStream = connection.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                String line;
                StringBuilder response = new StringBuilder();
                while ((line = reader.readLine())!= null) {
                    response.append(line);
                }
                reader.close();
                Log.d("WebResponsexxxxx", String.valueOf(response.toString().length()));
                Log.d("WebResponse", response.toString());
            } else {
                Log.e("WebRequest", "HTTP request failed with response code: " + responseCode);
            }
            connection.disconnect();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static boolean isProxyValid(String proxyHost, int proxyPort) {
        try {
            URL url = new URL("https://www.baidu.com");
            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));
            HttpURLConnection connection = (HttpURLConnection) url.openConnection(proxy);
            connection.setRequestMethod("GET");
            connection.connect();
            int responseCode = connection.getResponseCode();
            return (responseCode >= 200 && responseCode < 300);
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    public static boolean isProxyReachable(String proxyHost) {
        try {
            InetAddress address = InetAddress.getByName(proxyHost);
            return address.isReachable(5000);
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    private TextureView.SurfaceTextureListener mTextureListener = new TextureView.SurfaceTextureListener() {
        @Override
        public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surfaceTexture, int i, int i1) {
            mSurface = new Surface(surfaceTexture);
            initPlayerSettings();
        }

        @Override
        public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surfaceTexture, int i, int i1) { }

        @Override
        public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surfaceTexture) {
            return false;
        }

        @Override
        public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surfaceTexture) { }
    };

    private void initPlayerSettings() {
        VideoProxyCacheManager.getInstance().addCacheListener(mVideoUrl, new IVideoCacheListener() {
            @Override
            public void onCacheStart(VideoCacheInfo cacheInfo) {
            }
            @Override
            public void onCacheProgress(VideoCacheInfo cacheInfo) {
                Log.d(TAG,"cacheInfo mPercent" + cacheInfo.getPercent());
                Toast.makeText(VideoPlayActivity.this.getApplicationContext(),"" +  cacheInfo.getPercent(),Toast.LENGTH_SHORT).show();
            }
            @Override
            public void onCacheError(VideoCacheInfo cacheInfo, int errorCode) {
            }
            @Override
            public void onCacheForbidden(VideoCacheInfo cacheInfo) {
            }
            @Override
            public void onCacheFinished(VideoCacheInfo cacheInfo) {
            }
        });

            if (mPlayerType == 1) {
                mPlayer = new JeffPlayer(this.getApplicationContext(), PlayerType.EXO_PLAYER);
            } else {
                mPlayer = new JeffPlayer(this.getApplicationContext(), PlayerType.IJK_PLAYER);
            }
            mPlayer.setSeekType(SeekType.CLOSEST_SYNC);
            PlayerSettings playerSettings = new PlayerSettings();
            playerSettings.setLocalProxyEnable(mLocalProxyEnable);
            mPlayer.initPlayerSettings(playerSettings);

            mPlayer.setOnPreparedListener(mOnPreparedListener);
            mPlayer.setOnVideoSizeChangedListener(mOnVideoSizeChangedListener);
            mPlayer.setSurface(mSurface);
            try {
                mPlayer.setDataSource(this, Uri.parse(mVideoUrl), null);
            } catch (Exception e) {
                Toast.makeText(this, "player setDataSource failed", Toast.LENGTH_LONG).show();
                return;
            }
            mPlayer.prepareAsync();
        Log.d(TAG,"initPlayerSettings" +   mVideoUrl);
            Log.d(TAG,"initPlayerSettings" +   Uri.parse(mVideoUrl).getEncodedPath());
        Log.d(TAG,"initPlayerSettings gson" +  new Gson().toJson(Uri.parse(mVideoUrl)));

    }

    private SeekBar.OnSeekBarChangeListener mOnSeekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int i, boolean b) { }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            mHandler.removeMessages(MSG_UPDATE_VIDEOTIME);
        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            long totalDuration = mPlayer.getDuration();
            if (totalDuration > 0) {
                int progress = seekBar.getProgress();
                mPlayer.seekTo((long) (progress * 1.0f / MAX_PROGRESS * totalDuration));
                if (progress == MAX_PROGRESS) {
                    mHandler.removeMessages(MSG_UPDATE_VIDEOTIME);
                } else {
                    mHandler.sendEmptyMessage(MSG_UPDATE_VIDEOTIME);
                }
            } else {
                mHandler.sendEmptyMessage(MSG_UPDATE_VIDEOTIME);
            }
        }
    };

    private IPlayer.OnPreparedListener mOnPreparedListener = new IPlayer.OnPreparedListener() {
        @Override
        public void onPrepared() {
            mHandler.sendEmptyMessage(MSG_UPDATE_VIDEOTIME);
            mPlayer.start();

            updatePlayerBtn();
        }
    };

    private IPlayer.OnVideoSizeChangedListener mOnVideoSizeChangedListener = new IPlayer.OnVideoSizeChangedListener() {
        @Override
        public void onVideoSizeChanged(int width, int height, int rotationDegree, float pixelRatio, float darRatio) {
            LogUtils.i(TAG, "onVideoSizeChanged width="+width+", height="+height);
            mVideoWidth = width;
            mVideoHeight = height;
            mHandler.sendEmptyMessage(MSG_UPDATE_VIDEOSIZE);
        }
    };

    private View.OnClickListener mOnClickListener = view -> {
        if (mVideoStatus == VideoStatus.PLAY) {
            mPlayer.pause();
            mHandler.removeMessages(MSG_UPDATE_VIDEOTIME);
        } else {
            mPlayer.start();
            mHandler.sendEmptyMessage(MSG_UPDATE_VIDEOTIME);
        }
        updatePlayerBtn();
    };

    private void updateVideoSurfaceSize(int width, int height) {
        int baseWidth = mScreenSize.getWidth();
        float ratio = (width > height) ? height * 1.0f / width : width * 1.0f / height;
        int tempWidth = baseWidth;
        int tempHeight = (width > height) ? (int)(tempWidth * ratio) : (int)(tempWidth / ratio);
        mVideoView.setLayoutParams(new LinearLayout.LayoutParams(tempWidth, tempHeight));
    }

    private void updateVideoTimeInfo() {
        mTimeView.setVisibility(View.VISIBLE);
        long totalDuration = mPlayer.getDuration();
        long currentPosition = mPlayer.getCurrentPosition();
        mTimeView.setText(TimeUtils.getVideoTimeString(currentPosition) + "/" + TimeUtils.getVideoTimeString(totalDuration));

        int progress;
        if (totalDuration > 0) {
            progress = (int) (1.0f * currentPosition / totalDuration * MAX_PROGRESS);
            mProgressView.setProgress(progress);

            long bufferedPosition = mPlayer.getBufferedPosition();
            int bufferedProgress = (int) (1.0f * bufferedPosition / totalDuration * MAX_PROGRESS);
            mProgressView.setSecondaryProgress(bufferedProgress);
        }
        mHandler.removeMessages(MSG_UPDATE_VIDEOTIME);
        mHandler.sendEmptyMessageDelayed(MSG_UPDATE_VIDEOTIME, 1000);
    }

    private void updatePlayerBtn() {
        if (mVideoStatusBtn.getVisibility() == View.GONE) {
            mVideoStatusBtn.setVisibility(View.VISIBLE);
        }
        if (mPlayer.isPlaying()) {
            mVideoStatusBtn.setBackgroundResource(R.drawable.pause_icon);
            mVideoStatus = VideoStatus.PLAY;
        } else {
            mVideoStatusBtn.setBackgroundResource(R.drawable.play_icon);
            mVideoStatus = VideoStatus.PAUSE;
        }
    }

    private void removeHandlerMsg() {
        mHandler.removeMessages(MSG_UPDATE_VIDEOSIZE);
        mHandler.removeMessages(MSG_UPDATE_VIDEOTIME);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        removeHandlerMsg();
        try {
            mPlayer.release();
        }catch (Exception e){

        }
    }
}
